#include <stdlib.h>
#include <string.h>
#include "ast.h"

// 创建抽象语法树节点
// 参数：
// - type: 节点类型
// - token: 节点对应的Token
// 返回值：创建的AST节点指针
ASTNode* create_ast_node(ASTNodeType type, Token token) {
    ASTNode* node = (ASTNode*)malloc(sizeof(ASTNode));
    node->type = type;
    node->left = NULL;
    node->right = NULL;
    node->token = token;
    node->extra_data = NULL;
    return node;
}

// 释放AST节点及其子树资源
// 参数：
// - node: 要释放的AST节点指针
void free_ast_node(ASTNode* node) {
    if (!node) return;
    
    free_ast_node(node->left);
    free_ast_node(node->right);
    
    // 根据节点类型释放额外数据
    switch (node->type) {
        case NODE_CREATE_TABLE:
            if (node->extra_data) {
                CreateTableStmt* stmt = (CreateTableStmt*)node->extra_data;
                free(stmt->table_name);
                for (int i = 0; i < stmt->column_count; i++) {
                    free(stmt->columns[i].name);
                }
                free(stmt->columns);
                free(stmt);
            }
            break;
        case NODE_INSERT:
            if (node->extra_data) {
                InsertStmt* stmt = (InsertStmt*)node->extra_data;
                free(stmt->table_name);
                for (int i = 0; i < stmt->column_count; i++) {
                    free(stmt->columns[i]);
                }
                free(stmt->columns);
                for (int i = 0; i < stmt->value_count; i++) {
                    free_ast_node(stmt->values[i]);
                }
                free(stmt->values);
                free(stmt);
            }
            break;
        case NODE_SELECT:
            if (node->extra_data) {
                SelectStmt* stmt = (SelectStmt*)node->extra_data;
                for (int i = 0; i < stmt->column_count; i++) {
                    free_ast_node(stmt->columns[i]);
                }
                free(stmt->columns);
                free(stmt->table_name);
                free_ast_node(stmt->where_clause);
                free(stmt);
            }
            break;
        case NODE_DELETE:
            if (node->extra_data) {
                DeleteStmt* stmt = (DeleteStmt*)node->extra_data;
                free(stmt->table_name);
                free_ast_node(stmt->where_clause);
                free(stmt);
            }
            break;
        case NODE_DROP_TABLE:
            if (node->extra_data) {
                DropTableStmt* stmt = (DropTableStmt*)node->extra_data;
                free(stmt->table_name);
                free(stmt);
            }
            break;
        case NODE_ALTER_TABLE:
            if (node->extra_data) {
                AlterTableStmt* stmt = (AlterTableStmt*)node->extra_data;
                free(stmt->table_name);
                free(stmt->column_name);
                free(stmt);
            }
            break;
        case NODE_UPDATE:
            if (node->extra_data) {
                UpdateStmt* stmt = (UpdateStmt*)node->extra_data;
                free(stmt->table_name);
                for (int i = 0; i < stmt->set_count; i++) {
                    free(stmt->column_names[i]);
                    free_ast_node(stmt->values[i]);
                }
                free(stmt->column_names);
                free(stmt->values);
                free_ast_node(stmt->where_clause);
                free(stmt);
            }
            break;
        // 其他节点类型的释放逻辑
        default:
            if (node->extra_data) {
                free(node->extra_data);
            }
            break;
    }
    
    free(node);
}